extends CharacterBody2D
class_name BaseGolf
signal add_particl_event(position : Vector2)
signal look_event(value : bool)

@export var data_item : BaseKv
@onready var fly_line: Line2D = $FlyLine
@onready var check: CharacterBody2D = $FlyLine/Check
@onready var trail: Line2D = $Trail

const pre_fly_point_size : int = 50
var score : int = 0
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")#重力
var current_scene : Node2D#当前场景
var not_send : bool = true#静止后是否发送静止事件
var is_on_floor : bool#是否在地面
var round : int = -1

func _enter_tree() -> void:
	velocity = Vector2.ZERO
	current_scene = get_tree().current_scene
	current_scene.ball_emit.connect(_fly)
	current_scene.ball_rotation.connect(_set_fly_rotation)
	current_scene.ball_stop.connect(_on_ball_stop_event)
	if trail : trail.clear_points()

#击飞
func _fly(dir : Vector2) -> void :
	fly_line.hide()
	if is_same(dir,Vector2.ZERO) : return
	await get_tree().create_timer(2.0).timeout
	velocity = dir * data_item.fouce
	not_send = true

func _process(_delta: float) -> void:
	#同时满足横向移动力小于2.0并且在地面并且没有送静止事件，则发送静止事件
	if is_on_floor and not_send and abs(velocity.y) < 12.0 and abs(velocity.x) < 1.0 :
		current_scene.ball_stop.emit()
		not_send = false
	
	_key_input_check()

func _physics_process(delta: float) -> void:
	is_on_floor = false
	if not is_on_floor :
		#不在地面则受重力影响
		velocity.y += gravity * delta
	var collision = move_and_collide(velocity * delta)
	if collision :
		# 检测是否落地
		var collider = collision.get_collider()
		is_on_floor = collider.is_in_group("land")
		# 获取碰撞法线
		var normal = collision.get_normal()
		# 计算反弹方向
		velocity = velocity.bounce(normal) * data_item.bounce_rate
		if not_send : add_particl_event.emit(collision.get_position())

func _set_fly_rotation(target : Vector2) :
	fly_line.show()
	if fly_line.get_point_count() < 50 :
		for index in range(fly_line.get_point_count(),pre_fly_point_size) :
			fly_line.add_point(Vector2.ZERO,index)
	
	var v = target * data_item.fouce
	var del = 0.0
	var time = 1.0
	for index in pre_fly_point_size :
		v.y += gravity * get_physics_process_delta_time() * time
		var newv = v * get_physics_process_delta_time() * del
		del += time * 2.0
		fly_line.set_point_position(index,newv)
		

func _on_ball_stop_event() :
	round += 1

func _key_input_check() -> void :
	if Input.is_action_just_pressed("ui_accept") :
		look_event.emit(true)
	elif Input.is_action_just_released("ui_accept") :
		look_event.emit(false)
